import * as CryptoJS from "crypto-js";

const key = "donjin_ruien_key";

export async function generateRandomBytes(length: number): Promise<Uint8Array> {
  return new Promise<Uint8Array>((resolve, reject) => {
    CryptoJS.lib.WordArray.random(length, (err, wordsArray) => {
      if (err) {
        reject(err);
      } else {
        const byteArray = new Uint8Array(wordsArray.words.length * 4);
        wordsArray.words.forEach((word, i) => {
          byteArray[i * 4] = (word >> 24) & 0xff;
          byteArray[i * 4 + 1] = (word >> 16) & 0xff;
          byteArray[i * 4 + 2] = (word >> 8) & 0xff;
          byteArray[i * 4 + 3] = word & 0xff;
        });
        resolve(byteArray);
      }
    });
  });
}
const CryptoUtils = {
  encrypt: async (data: Record<string, any>): Promise<string> => {
    try {
      const iv = await generateRandomBytes(16);
      if (!iv || iv.length !== 16) {
        console.error("Invalid IV:", iv);
        throw new Error("Invalid IV");
      }
      console.log("Generated IV:", iv);

      const keyBytes = CryptoJS.enc.Utf8.parse(key);
      const cipherText = CryptoJS.AES.encrypt(JSON.stringify(data), keyBytes, {
        iv: CryptoJS.enc.Hex.stringify(iv),
      });
      return cipherText.toString();
    } catch (error) {
      console.error("Error encrypting data:", error);
      throw error;
    }
  },

  decrypt: (ciphertext: string): Record<string, any> | null => {
    try {
      console.log("Received Ciphertext:", ciphertext);

      const keyBytes = CryptoJS.enc.Utf8.parse(key);
      const bytes = CryptoJS.AES.decrypt(ciphertext, keyBytes, {
        format: {
          parse: function (str) {
            const hexString = CryptoJS.enc.Hex.stringify(
              CryptoJS.enc.Utf8.parse(str)
            );
            return CryptoJS.enc.Hex.parse(hexString);
          },
          stringify: function (cipherText) {
            return CryptoJS.enc.Utf8.stringify(
              CryptoJS.enc.Hex.parse(cipherText)
            );
          },
        },
      });

      // Log the intermediate steps
      console.log("Decrypted Hex:", CryptoJS.enc.Hex.stringify(bytes));

      if (!bytes || bytes.sigBytes === 0) {
        console.error("Decryption failed or result is empty.");
        return null; // 返回一个空对象或适当的默认值
      }

      const decryptedText = bytes.toString(CryptoJS.enc.Utf8);
      console.log("Decrypted Text:", decryptedText);

      try {
        return JSON.parse(decryptedText);
      } catch (jsonError) {
        console.error("Error parsing decrypted JSON:", jsonError);
        throw jsonError;
      }
    } catch (error) {
      console.error("Error decrypting ciphertext:", error);
      throw error;
    }
  },
};


export default CryptoUtils;
